#include <stdint.h> 
#include <stdlib.h>
#include <stdio.h>
#include <string.h>


// 1、 BMP文件头（14字节）
typedef struct BITMAPFILEHEADER                      /**** BMP file header structure ****/  
{  
    uint32_t  bfSize;           /* Size of file */  
    uint16_t bfReserved1;      /* Reserved */  
    uint16_t bfReserved2;      /* ... */  
    uint32_t  bfOffBits;        /* Offset to bitmap data */  
} MyBITMAPFILEHEADER;

// 2、位图信息头（40字节）
typedef struct BITMAPINFOHEADER                      /**** BMP file info structure ****/  
{  
    uint32_t  biSize;           /* Size of info header */  
    int            biWidth;          /* Width of image */  
    int            biHeight;         /* Height of image */  
    uint16_t biPlanes;         /* Number of color planes */  
    uint16_t biBitCount;       /* Number of bits per pixel */  
    uint32_t  biCompression;    /* Type of compression to use */  
    uint32_t  biSizeImage;      /* Size of image data */  
    int            biXPelsPerMeter;  /* X pixels per meter */  
    int            biYPelsPerMeter;  /* Y pixels per meter */  
    uint32_t  biClrUsed;        /* Number of colors used */  
    uint32_t  biClrImportant;   /* Number of important colors */  
} MyBITMAPINFOHEADER;

// 3、颜色表
typedef struct tagRGBQUAD{  
    uint8_t rgbBlue;//蓝色的亮度（值范围为0-255)  
    uint8_t rgbGreen;//绿色的亮度（值范围为0-255)  
    uint8_t rgbRed;//红色的亮度（值范围为0-255)  
    uint8_t rgbReserved;//保留，必须为0  
}RGBQUAD;

static void flip(uint8_t *buf, uint32_t image_width,uint32_t image_height) {
	int index = 3;
	int h = 0,w = 0;
	for (h = 0; h < image_height/2; h++) {
		for (w = 0; w < image_width; w++) {
			uint32_t iCoordM = index*(h*(image_width) + w);
			uint32_t iCoordN = index*((image_height - h -1)*(image_width) + w);
			uint8_t Tmp = buf[iCoordM];
			buf[iCoordM] = buf[iCoordN];
			buf[iCoordN] = Tmp;
			Tmp = buf[iCoordM+1];
			buf[iCoordM + 1] = buf[iCoordN + 1]; 
			buf[iCoordN + 1] = Tmp;
			Tmp = buf[iCoordM + 2];
			buf[iCoordM + 2] = buf[iCoordN + 2];
			buf[iCoordN + 2] = Tmp;
		}
	}
}
static const int LEN = 1920 * 1080 * 3 + 64;
static uint8_t buf[LEN] = {0};
extern "C" {	
void saveBmp(const char *filename, const uint8_t *rgbbuf,uint32_t width,uint32_t height) ;
}
void saveBmp(const char *filename, const uint8_t *rgbbuf,uint32_t width,uint32_t height)  {
	::memset(buf, 0, LEN);
	int bufSize = width*height*3;  
	memcpy(buf, rgbbuf,  sizeof(BITMAPINFOHEADER)+ bufSize);
	
    MyBITMAPFILEHEADER bfh;  
    MyBITMAPINFOHEADER bih;  
    /* Magic number for file. It does not fit in the header structure due to alignment requirements, so put it outside */  
    uint16_t bfType=0x4d42;             
    bfh.bfReserved1 = 0;  
    bfh.bfReserved2 = 0;  
    bfh.bfSize = 2+sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER)+width*height*3;  
    bfh.bfOffBits = 0x36;  
  
    bih.biSize = sizeof(BITMAPINFOHEADER);  
    bih.biWidth = width;  
    bih.biHeight = height;  
    bih.biPlanes = 1;  
    bih.biBitCount = 24;  
    bih.biCompression = 0;  
    bih.biSizeImage = 0;  
    bih.biXPelsPerMeter = 5000;  
    bih.biYPelsPerMeter = 5000;  
    bih.biClrUsed = 0;  
    bih.biClrImportant = 0;  
  
    FILE *file = fopen(filename, "wb");  
    if (!file)  
    {  
        printf("Could not write file\n");  
        return;  
    }  
  
    /*Write headers*/  
    fwrite(&bfType,sizeof(bfType),1,file);  
    fwrite(&bfh,sizeof(bfh),1, file);  
    fwrite(&bih,sizeof(bih),1, file);  
	flip(buf, width, height);
    fwrite(buf, bufSize,1,file);  
    fclose(file);  
}